﻿using System;
using System.Collections.Generic;

namespace Sustainalytics.LongRunningTaskManager.Interface
{
    /// <summary>
    /// Snapshot of a Long Running Task instance.
    /// </summary>
    public class LongRunningTaskInstanceSnapshot : IEqualityComparer<LongRunningTaskInstanceSnapshot>
    {
        /// <summary>
        /// Task instance ID.
        /// </summary>
        public string Id { get; set; }

        /// <summary>
        /// Task instance title.
        /// </summary>
        public string Title { get; set; }

        /// <summary>
        /// Parameter passed when the task was started.
        /// </summary>
        public string ParamJson { get; set; }

        /// <summary>
        /// Task result.
        /// </summary>
        public ILongRunningTaskResult Result { get; set; }

        /// <summary>
        /// Task result type.
        /// </summary>
        public LongRunningTaskResultTypeEnum? ResultType { get; set; }

        /// <summary>
        /// Task instance status.
        /// </summary>
        public LongRunningTaskInstanceStatus Status { get; set; }

        /// <summary>
        /// Task type.
        /// </summary>
        public LongRunningTaskTypeEnum Type { get; set; }

        /// <summary>
        /// Username associated to current task snapshot.
        /// </summary>
        public string Username { get; set; }

        /// <summary>
        /// Date when snapshot was created.
        /// </summary>
        public DateTime DateCreated { get; set; }

        /// <summary>
        /// Date when current task instance snapshot was created.
        /// </summary>
        public DateTime SnapshotDateCreated { get; set; }

        /// <summary>
        /// Order of occurence of current task.
        /// </summary>
        public long Order { get; set; }


        /// <summary>
        /// Ctor.
        /// </summary>
        public LongRunningTaskInstanceSnapshot()
        {
            this.SnapshotDateCreated = DateTime.UtcNow;
        }

        /// <summary>
        /// Ctor.
        /// </summary>
        /// <param name="taskInstance"> Task instance for which to create the snapshot. </param>
        public LongRunningTaskInstanceSnapshot(ILongRunningTaskInstance taskInstance)
            :this()
        {
            this.Id = taskInstance.Id;
            this.Title = taskInstance.Title;
            this.ParamJson = taskInstance.TaskContext.ParamJson;
            this.Result = taskInstance.Result;
            this.ResultType = taskInstance.Result == null ? (LongRunningTaskResultTypeEnum?)null : taskInstance.Result.Type;
            this.Status = taskInstance.Status;
            this.Type = taskInstance.Type;
            this.Username = taskInstance.TaskContext.Ticket == null ? null : taskInstance.TaskContext.Ticket.Identity.Name;
            this.DateCreated = taskInstance.DateCreated;
            this.Order = taskInstance.Order;
        }


        public bool Equals(LongRunningTaskInstanceSnapshot x, LongRunningTaskInstanceSnapshot y)
        {
            if (x == null && y == null)
                return true;

            if (x == null || y == null)
                return false;

            var ok = ((x.Id == null && y.Id == null) || x.Id == y.Id)
                && ((x.Title == null && y.Title == null) || x.Title == y.Title)
                && ((x.ParamJson == null && y.ParamJson == null) || x.ParamJson == y.ParamJson)
                && ((x.Result == null && y.Result == null) || (x.Result != null && x.Result.Equals(x.Result, y.Result)) || (y.Result != null && y.Result.Equals(x.Result, y.Result)))
                && x.ResultType == y.ResultType
                && new LongRunningTaskInstanceStatus().Equals(x.Status, y.Status)
                && x.Type == y.Type
                && ((x.Username == null && y.Username == null) || x.Username == y.Username)
                && x.DateCreated.Date == y.DateCreated.Date
                && x.SnapshotDateCreated.Date == y.SnapshotDateCreated.Date
                && x.Order == y.Order;

            return ok;
        }

        public int GetHashCode(LongRunningTaskInstanceSnapshot obj)
        {
            return obj.Id.GetHashCode();
        }
    }
}
